package cn.jee.redis;

import cn.jee.redis.domain.Stu;
import redis.clients.jedis.Jedis;
import java.util.*;

public class StuMis {
  private Jedis jedis;

  public StuMis() {
    jedis = new Jedis(); // 默认连接 localhost:6379
  }

  // 清空数据库
  public void clear() {
    jedis.flushAll();
  }

  // 产生一个学生学号（使用Redis的incr命令）
  public long newId() {
    return jedis.incr("stu:id");
  }

  /**
   * 给Stu一个学号，然后保存在stu:学号的hash表中
   * 同时保存java成绩在sorted set中
   * 保存math成绩在sorted set中
   */
  public void add(Stu stu) {
    long id = newId();
    stu.setId(id);

    String key = "stu:" + id;

    Map<String, String> stuMap = new HashMap<>();
    stuMap.put("id", String.valueOf(id));
    stuMap.put("username", stu.getUsername());
    stuMap.put("java", String.valueOf(stu.getJava()));
    stuMap.put("math", String.valueOf(stu.getMath()));

    jedis.hmset(key, stuMap); // 保存 Hash

    jedis.zadd("java", stu.getJava(), String.valueOf(id)); // Java成绩
    jedis.zadd("math", stu.getMath(), String.valueOf(id)); // Math成绩
  }

  // 数学成绩最高的5个人的姓名
  public String[] top5ByMath() {
    Set<String> topIds = (Set<String>) jedis.zrevrange("math", 0, 4);
    List<String> names = new ArrayList<>();

    for (String id : topIds) {
      String name = jedis.hget("stu:" + id, "username");
      if (name != null) {
        names.add(name);
      }
    }

    return names.toArray(new String[0]);
  }

  // 成绩在min和max之间的java成绩
  public double[] betweenJava(double min, double max) {
    Set<String> ids = (Set<String>) jedis.zrangeByScore("java", min, max);
    List<Double> scores = new ArrayList<>();

    for (String id : ids) {
      String scoreStr = jedis.hget("stu:" + id, "java");
      if (scoreStr != null) {
        scores.add(Double.parseDouble(scoreStr));
      }
    }

    return scores.stream().mapToDouble(Double::doubleValue).toArray();
  }

  // 按学号查找，没有返回null
  public Stu findById(long id) {
    String key = "stu:" + id;
    if (!jedis.exists(key)) {
      return null;
    }

    Map<String, String> map = jedis.hgetAll(key);
    Stu stu = new Stu();
    stu.setId(Long.parseLong(map.get("id")));
    stu.setUsername(map.get("username"));
    stu.setJava(Double.parseDouble(map.get("java")));
    stu.setMath(Double.parseDouble(map.get("math")));

    return stu;
  }

  // 按java成绩从低到高分页查询
  public List<Stu> pageByJava(int page, int size) {
    int start = (page - 1) * size;
    int end = start + size - 1;

    Set<String> ids = (Set<String>) jedis.zrange("java", start, end);
    List<Stu> students = new ArrayList<>();

    for (String id : ids) {
      Stu stu = findById(Long.parseLong(id));
      if (stu != null) {
        students.add(stu);
      }
    }

    return students;
  }
}
